<?php
// +-------------------------------------------------------------------------------
// | DingZone [ A Rapid Development Framework For Dingtalk ]
// +-------------------------------------------------------------------------------
// | 企业管理相关Controller v1.0
// |
// | Copyright (c) 2014-2018 http://www.heimalanshi.com All rights reserved.
// | Author : Jie
// | Date : 2018-08-09
// +-------------------------------------------------------------------------------

namespace app\core\controller\site;

use app\core\model\CacheKey;
use app\core\model\Enterprise;
use app\core\model\EnterpriseModule;
use app\core\model\SiteConfig;
use app\core\model\SiteModule;
use common\Encryption;
use ding\ApiHelper;
use ding\model\MediaTypeEnum;
use ding\request\MicroappSaveRequest;
use think\Config;
use think\Cookie;

class EnterpriseController extends SiteBaseController {

    /**
     * 企业列表
     *
     * @return \think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function all() {
        $key = DEFAULT_DECRYPT_KEY;

        $enterprises = Enterprise::all();
        $enterpriseModuleCounts = EnterpriseModule::groupCountByEid();
        foreach ($enterprises as &$enterprise) {
            $enterprise['corpid'] = Encryption::decrypt($enterprise['corpid'], $key);
            $enterprise['corpsecret'] = Encryption::decrypt($enterprise['corpsecret'], $key);
            $enterprise['appid'] = Encryption::decrypt($enterprise['appid'], $key);
            $enterprise['appsecret'] = Encryption::decrypt($enterprise['appsecret'], $key);
            $enterprise['module_cnt'] = 0;
            foreach ($enterpriseModuleCounts as $enterpriseModuleCount) {
                if ($enterpriseModuleCount['enterprise_id'] == $enterprise['id']) {
                    $enterprise['module_cnt'] = $enterpriseModuleCount['cnt'];
                }
            }
        }

        $this->assign("enterprises", $enterprises);
        return view();
    }

    /**
     * 编辑企业信息
     *
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function edit() {
        $row = [];
        $id = input("post.id");
        $row['title'] = input("post.title");
        $row['logo'] = input("post.logo");
        $row['contacter'] = input("post.contacter");
        $row['phone'] = input("post.phone");
        $row['description'] = input("post.description");
        $row['corpid'] = input("post.corpid");
        $row['corpsecret'] = input("post.corpsecret");
        $row['appid'] = input("post.appid");
        $row['appsecret'] = input("post.appsecret");

        $key = DEFAULT_DECRYPT_KEY;
        if (!empty($row['corpid'])) {
            $row['corpid'] = Encryption::encrypt($row['corpid'], $key);
        }
        if (!empty($row['corpsecret'])) {
            $row['corpsecret'] = Encryption::encrypt($row['corpsecret'], $key);
        }
        if (!empty($row['appid'])) {
            $row['appid'] = Encryption::encrypt($row['appid'], $key);
        }
        if (!empty($row['corpid'])) {
            $row['appsecret'] = Encryption::encrypt($row['appsecret'], $key);
        }


        if (empty($id) || empty($row['title'])) {
            $this->error("参数错误");
        }

        $enterprise = Enterprise::get($id);
        if (empty($enterprise)) {
            $this->error("未找到该企业");
        }

        $ret = Enterprise::update($row, $id);

        if ($ret) {
            $this->success("修改成功");
        } else {
            $this->error("修改失败");
        }
    }

    /**
     * 新增企业信息
     */
    public function add() {
        $row = [];
        $row['title'] = input("post.title");
        $row['logo'] = input("post.logo");
        $row['contacter'] = input("post.contacter");
        $row['phone'] = input("post.phone");
        $row['description'] = input("post.description");
        $row['corpid'] = input("post.corpid");
        $row['corpsecret'] = input("post.corpsecret");
        $row['appid'] = input("post.appid");
        $row['appsecret'] = input("post.appsecret");
        if (empty($row['title'])) {
            $this->error("企业名称不能为空");
        }

        $key = DEFAULT_DECRYPT_KEY;
        if (!empty($row['corpid'])) {
            $row['corpid'] = Encryption::encrypt($row['corpid'], $key);
        }
        if (!empty($row['corpsecret'])) {
            $row['corpsecret'] = Encryption::encrypt($row['corpsecret'], $key);
        }
        if (!empty($row['appid'])) {
            $row['appid'] = Encryption::encrypt($row['appid'], $key);
        }
        if (!empty($row['appsecret'])) {
            $row['appsecret'] = Encryption::encrypt($row['appsecret'], $key);
        }

        $id = Enterprise::add($row);
        if (empty($id)) {
            $this->error("数据添加失败");
        }

        $this->success("添加成功");
    }

    /**
     * 删除企业
     *
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function delete() {
        $eid = input("post.id");
        $enterprise = Enterprise::get($eid);
        if (empty($enterprise)) {
            $this->error("未找到该企业信息");
        }

        $enterpriseModules = EnterpriseModule::getByEid($eid, EnterpriseModule::ENTERPRISE_MODULE_STATUS_NORMAL);
        if (!empty($enterpriseModules)) {
            $this->error("当前企业有正在使用的模块，无法删除，请先取消企业对模块的授权之后再进行删除");
        }

        $ret = Enterprise::delete($eid);
        if ($ret === false) {
            $this->error("删除失败");
        } else {
            $this->success("删除成功");
        }
    }

    /**
     * 企业详情
     *
     * @return \think\response\View
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function detail() {
        $eid = input("get.eid");
        $enterprise = Enterprise::get($eid);
        if (empty($enterprise)) {
            $this->error("参数错误，找不到该企业信息");
        }

        // 企业拥有的模块
        $enterpriseModules = EnterpriseModule::getByEid($eid);
        $enterpriseModules = EnterpriseModule::batchCheckExpired($enterpriseModules);
        $enterpriseModules = remap($enterpriseModules, "module_id");

        // 所有模块
        $allModules = SiteModule::getAllModules();
        $usingModules = [];//正在使用的模块
        $expiredModules = [];//已经过期的模块
        $revokedModules = [];//已经被回收权限的模块
        $availableModules = [];
        foreach ($allModules as $module) {
            if (!isset($module['id'])) {
                // 未安装的模块，不需要显示
                continue;
            }
            $mid = $module['id'];
            if (isset($enterpriseModules[$mid])) {
                $enterpriseModule = $enterpriseModules[$mid];
                $module['enterpriseModule'] = $enterpriseModule;
                if ($enterpriseModule['status'] == EnterpriseModule::ENTERPRISE_MODULE_STATUS_NORMAL) {
                    $usingModules[$mid] = $module;
                } else if ($enterpriseModule['status'] == EnterpriseModule::ENTERPRISE_MODULE_STATUS_EXPIRED) {
                    $expiredModules[$mid] = $module;
                } else if ($enterpriseModule['status'] == EnterpriseModule::ENTERPRISE_MODULE_STATUS_REVOKED) {
                    if ($module['status'] == SiteModule::MODULE_STATUS_ACTIVE) {
                        $revokedModules[$mid] = $module;
                    }
                }
            } else {
                if ($module['status'] == SiteModule::MODULE_STATUS_ACTIVE) {
                    $module['enterpriseModule'] = false;
                    $availableModules[$mid] = $module;
                }
            }
        }

        $this->assign("modules", array_merge($usingModules, array_merge($expiredModules, array_merge($revokedModules, $availableModules))));
        $this->assign("enterprise", $enterprise);
        return view();
    }

    /**
     * mock企业
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function mock() {
        $eid = input("get.eid");
        $enterprise = Enterprise::get($eid);
        if (empty($enterprise)) {
            $this->error("参数错误，找不到该企业信息");
        }

        $user = [
            'id' => '-1',
            'username' => $this->siteAdmin['username'] . '(mock)',
            'password' => '',
            'enterprise_id' => $eid,
            'gmt_created' => time(),
            'gmt_last_login' => time(),
            'last_login_ip' => '',
            'status' => 'normal',
            'avatar' => $this->siteAdmin['avatar'],
            'is_admin' => true,
            'showname' => $this->siteAdmin['username'] . '(mock)',
            'position' => [],
            'is_senior' => [],
            'openId' => '',
            'dingId' => '',
            'unionid' => '',
            'jobnumber' => '',
            'sex' => 1
        ];
        $user['enterprise'] = $enterprise;

        session(SESSION_CORE_ENTERPRISE_USER, $user);
        Cookie::forever(COOKIE_CORE_CURRENT_ENTERPRISE_ID, $eid);

        $this->redirect("/core/enterprise?eid=" . $eid);
    }

    /**
     * 回收企业对模块的使用权限
     *
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function revoke() {
        $moduleName = input("param.moduleName");
        $eid = input("param.eid");

        $enterprise = Enterprise::get($eid);
        if (empty($enterprise)) {
            $this->error("参数错误，找不到该企业");
        }

        $module = SiteModule::getByName($moduleName);
        if (empty($module)) {
            $this->error("参数错误，找不到该模块");
        }

        $enterpriseModule = EnterpriseModule::getById($eid, $module['id']);
        if (empty($enterpriseModule)) {
            $this->error("参数错误，该企业未授权过该模块");
        }

        $ret = EnterpriseModule::update([
            'status' => EnterpriseModule::ENTERPRISE_MODULE_STATUS_REVOKED,
            'agent_id' => null
        ], $module['id'], $eid);

        if (!$ret) {
            $this->error("撤销失败");
        }

        if (!empty($enterprise['corpid']) && !empty($enterpriseModule['agent_id'])) {
            //删除微应用
            $apiHelper = new ApiHelper($enterprise, null);
            $apiHelper->microappDelete($enterpriseModule['agent_id']);
        }

        if ($ret) {
            CacheKey::remove("enterprise.menus");

            $this->success("撤销成功");
        }
    }

    /**
     * 授权企业使用模块
     *
     * @throws \ReflectionException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function grant() {
        $moduleName = input("param.moduleName");
        $eid = input("param.eid");
        $expiry = input("param.expiry");

        $enterprise = Enterprise::get($eid);
        if (empty($enterprise)) {
            $this->error("参数错误，找不到该企业");
        }

        $module = SiteModule::getByName($moduleName);
        if (empty($module)) {
            $this->error("参数错误，找不到该模块");
        }

        $data = [
            'status' => EnterpriseModule::ENTERPRISE_MODULE_STATUS_NORMAL
        ];
        if (!empty($expiry)) {
            $data['expiry'] = strtotime($expiry);
        }
        // 先查找是否存在
        $enterpriseModule = EnterpriseModule::getById($eid, $module['id']);
        if (empty($enterpriseModule)) {
            $data['module_id'] = $module['id'];
            $data['enterprise_id'] = $eid;
            $ret = EnterpriseModule::add($data);
            $needCreateMicroapp = true;
        } else {
            $ret = EnterpriseModule::update($data, $module['id'], $eid);
            $needCreateMicroapp = empty($enterpriseModule['agent_id']) ? true : false;
        }

        if (!$ret) {
            $this->error("授权失败");
        }

        if (!empty($enterprise['corpid']) && !empty($module['microapp']) && $needCreateMicroapp) {
            //创建微应用
            if (is_string($module['microapp'])) {
                $module['microapp'] = json_decode($module['microapp'], true);
            }
            // 新建一个微应用
            $apiHelper = new ApiHelper($enterprise, null);
            $logo = realpath(APP_PATH . "../addons/" . $module['name'] . "/logo.png");
            if (!file_exists($logo)) {
                $logo = realpath(APP_PATH . "../public/static/images/module.png");
            }
            $response = $apiHelper->mediaUpload($logo, MediaTypeEnum::IMAGE);
            $mediaId = fetch($response, "media_id");
            $mobile = $this->_processUrl(fetch($module['microapp'], 'mobile'), $eid);
            $pc = $this->_processUrl(fetch($module['microapp'], 'pc'), $eid);
            $title = fetch($module['microapp'], 'title', '');
            if (empty($title)) {
                $title = $module['title'];
            }

            $request = MicroappSaveRequest::microappCreateRequest($mediaId, mb_substr($title, 0, 10, "utf-8"),
                mb_substr($module['description'], 0, 20, "utf-8"), $mobile);
            $request->setPcHomepageUrl($pc);
            $request->setOmpLink(request()->domain() . "/core/enterprise?eid=" . $eid . "#module_" . $module['id']);
            $response = $apiHelper->microappCreate($request);
            $agentId = $response;

            if (!empty($agentId)) {
                EnterpriseModule::update([
                    'agent_id' => $agentId
                ], $module['id'], $eid);
            }
        }

        CacheKey::remove("enterprise.menus");
        $this->success("授权成功");
    }

    private static function _processUrl($url, $eid) {
        if (empty($url)) {
            return $url;
        }
        if (!startsWith($url, "http://") && !startsWith($url, "https://")) {
            $url = request()->domain() . $url;
        }
        if (strpos($url, '?') !== FALSE) {
            $url .= "&";
        } else {
            $url .= "?";
        }
        $url .= "eid=" . $eid;
        return $url;
    }
}
